#include "head.h"


//int serveOrder(MYSQL *mysql, train_t *train, threadPool_t *threadPool, int sockfd){
//    switch(train->type){
//    case CD: cdOrder(mysql, threadPool->recordUserId[sockfd], sockfd, train->buf); break;
//    case LS: lsOrder(mysql, threadPool->recordUserId[sockfd], sockfd, train->buf); break;
//    case MKDIR: mkdirOrder(mysql, threadPool->recordUserId[sockfd], sockfd, train->buf); break;
//    case RMDIR: rmdirOrder(mysql, threadPool->recordUserId[sockfd], sockfd, train->buf); break;
//    case RMDIR_R: rmdir_rOrder(mysql, threadPool->recordUserId[sockfd], sockfd, train->buf); break;
//    case PWD: pwdOrder(mysql, threadPool->recordUserId[sockfd], sockfd); break;
//    case REMOVE: removeOrder(mysql, threadPool->recordUserId[sockfd], sockfd, train->buf); break;
//    default: RETERROR2("Invalid order."); break;
//    }
//    return 0;
//}

int checkMD5(MYSQL *mysql, char *MD5){
    char sql[1024] = {0};
    sprintf(sql, "select count(*) from file_info where fileMD5Value = '%s';", MD5);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(rows);
    int count = atoi(row[0]);
    return count;
}

int findPath(MYSQL *mysql, int userid, int sockfd, char *destPath, int *destPos){
    int curpos;
    if(destPath[0] == '/'){
        char sql[1024] = {0};
        sprintf(sql, "select id from file_info where parentId = 0 and userId = %d;", userid);
        int qret = mysql_query(mysql, sql);
        MYSQL_RES *rows = mysql_store_result(mysql);
        MYSQL_ROW row = mysql_fetch_row(rows);
        curpos = atoi(row[0]);
    }else{
        char sql[1024] = {0};
        sprintf(sql, "select pwd from user_info where id = %d;", userid);
        int qret = mysql_query(mysql, sql);
        MYSQL_RES *rows = mysql_store_result(mysql);
        MYSQL_ROW row = mysql_fetch_row(rows);
        curpos = atoi(row[0]);
    }
    char *saveptr;
    char *p = strtok_r(destPath, "/", &saveptr);
    while(p != NULL){
        if(!strcmp(p, "..")){
            char sql[1024] = {0};
            sprintf(sql, "select parentId from file_info where id = %d;", curpos);
            int qret = mysql_query(mysql, sql);
            MYSQL_RES *rows = mysql_store_result(mysql);
            MYSQL_ROW row = mysql_fetch_row(rows);
            int parentid = atoi(row[0]);
            if(parentid == 0){
                RETERROR2("Invalid path.");
                return -1;
            }
            curpos = parentid;
        }else if(!strcmp(p, ".")){
            printf("cdOrder\n");
            /* continue; */
        }else{
            char sql[1024] = {0};
            sprintf(sql, "select id from file_info where parentId = %d and fileName = '%s' and fileType = 'd';", curpos, p);
            int qret = mysql_query(mysql, sql);
            MYSQL_RES *rows = mysql_store_result(mysql);
            int count = mysql_num_rows(rows);
            if(count == 0){
                printf("count = %d\n", count);
                RETERROR2("Invalid path.");
                return -1;
            }
            MYSQL_ROW row = mysql_fetch_row(rows);
            curpos = atoi(row[0]);
        }
        p = strtok_r(NULL, "/", &saveptr);
    }
    *destPos = curpos;
    return 0;
}

int divPath(char *parent, char *destFile, char *destPath){
    int len = strlen(destPath);
    bool slash = false;
    for (int i = len-1; i > 0; --i){
        if(destPath[i] == '/'){
            destPath[i] = '?';
            slash = true;
            break;
        }
    }
    if(slash){
        char *saveptr;
        parent = strtok_r(destPath, "?", &saveptr);
        destFile = strtok_r(NULL, "?", &saveptr);
    }else{
        if(destPath[0] == '/'){
            parent[0] = '/';
            destFile = strtok(destPath, "/");
        }else{
            strcpy(destFile, destPath);
        }
    }
    return 0;
}

int cdOrder(MYSQL *mysql, int userid, int sockfd, char *destPath){
    printf("destPath :%s\n", destPath);
    int destPos;
    int ret = findPath(mysql, userid, sockfd, destPath, &destPos);
    if(ret == -1){
        return -1;
    }
    char sql[1024] = {0};
    sprintf(sql, "update user_info set pwd = %d where id = %d;", destPos, userid);
    mysql_query(mysql, sql);
        RETOK("CD success.");
    return 0;
}

int lsOrder(MYSQL *mysql, int userid, int sockfd, char *destPath){
    int destPos;
    int ret = findPath(mysql, userid, sockfd, destPath, &destPos);
    if(ret == -1){
        return -1;
    }
    char sql[1024] = {0};
    sprintf(sql, "select fileName from file_info where parentId = %d;", destPos);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    char lsret[4096] = {0};
    for(int i = 0; i < (int)mysql_num_rows(rows); ++i){
        MYSQL_ROW row = mysql_fetch_row(rows);
        char buf[1024] = {0};
        sprintf(buf, "%s\t", row[0]);
        strcat(lsret, buf);
    }
    if((int)mysql_num_rows(rows) == 0){
        TLVResponse(sockfd, "no files", IS_OK);
        return 0;
    }
    TLVResponse(sockfd, lsret, IS_OK);
    return 0;
}

int mkdirOrder(MYSQL *mysql, int userid, int sockfd, char *destPath){
    int destPos;
    char parent[1024] = {0};
    char newDir[1024] = {0};
    divPath(parent, newDir, destPath);
    int ret = findPath(mysql, userid, sockfd, parent, &destPos);
    if(ret == -1){
        return -1;
    }
    char sql[1024] = {0};
    sprintf(sql, "select id from file_info where parentId = %d and fileName = '%s';", destPos, newDir);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    int count = mysql_num_rows(rows);
    if(count){
        RETERROR2("Dir name used, change another.");
        return -1;
    }
    bzero(sql, 1024);
    sprintf(sql, "select path from file_info where id = %d;", destPos);
    qret = mysql_query(mysql, sql);
    rows = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(rows);
    char newPath[1024] = {0};
    if(strlen(row[0]) == 1){
        sprintf(newPath, "/%s", newDir);    
    }
    else{
        sprintf(newPath, "%s/%s", row[0], newDir);
    }
    bzero(sql, 1024);
    sprintf(sql, "insert into file_info values(null, '%s', %d, '0', %d, '%s', 'd', 0);", newDir, destPos, userid, newPath);
    qret = mysql_query(mysql, sql);
    if(qret == 0){
        RETOK("MKDIR success.");
    }
    else{
        RETMYSQLERROR(qret, "mysql_query");
    }
    return 0;
}

int rmdirOrder(MYSQL *mysql, int userid, int sockfd, char *destPath){
    int destPos;
    int ret = findPath(mysql, userid, sockfd, destPath, &destPos);
    if(ret == -1){
        return -1;
    }
    char sql[1024] = {0};
    sprintf(sql, "select id from file_info where userId = %d and parentId = 0;", userid);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(rows);
    int userRootId = atoi(row[0]);
    if(destPos == userRootId){
        RETERROR2("Banned to delete root dir.");
        return -1;
    }
    bzero(sql, 1024);
    sprintf(sql, "delete from file_info where id = %d;", destPos);
    qret = mysql_query(mysql, sql);
    if(qret == 0){
        RETOK("RMDIR success.");
    }
    return 0;
}

int rmdir_r(MYSQL *mysql, int userid, int sockfd, int destPos){
    char sql[1024] = {0};
    sprintf(sql, "select id, fileMD5Value, fileType from file_info where parentId = %d", destPos);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    for(int i = 0; i < (int)mysql_num_rows(rows); ++i){
        MYSQL_ROW row = mysql_fetch_row(rows);
        int id = atoi(row[0]);
        char MD5[1024] = {0};
        char fileType[4] = {0};
        strcpy(MD5, row[1]);
        strcpy(fileType, row[2]);
        if(fileType[0] == 'f'){
            int ret = checkMD5(mysql, MD5);
            if(ret == 1){
                remove(MD5);
            }
        }else{
            rmdir_r(mysql, userid, sockfd, id);
        }
        bzero(sql, 1024);
        sprintf(sql, "delete from file_info where id = %d;", id);
        qret = mysql_query(mysql, sql);
    }
    RETOK("RMDIR_R success.");
    return 0;
}

int rmdir_rOrder(MYSQL *mysql, int userid, int sockfd, char *destPath){
    int destPos;
    int ret = findPath(mysql, userid, sockfd, destPath, &destPos);
    rmdir_r(mysql, userid, sockfd, destPos);
    return 0;
}

int pwdOrder(MYSQL *mysql, int userid, int sockfd){
    char sql[1024] = {0};
    sprintf(sql, "select pwd from user_info where id = %d;", userid);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(rows);
    int pwdid = atoi(row[0]);
    bzero(sql, 1024);
    sprintf(sql, "select path from file_info where id = %d;", pwdid);
    qret = mysql_query(mysql, sql);
    rows = mysql_store_result(mysql);
    row = mysql_fetch_row(rows);
    char pwdbuf[1024] = {0};
    strcpy(pwdbuf, row[0]);
    
    /* printf("pwd %s\n", row[0]); */

    TLVResponse(sockfd, pwdbuf, IS_OK);
    return 0;
}

int removeOrder(MYSQL *mysql, int userid, int sockfd, char *destPath){
    int destPos;
    char parent[1024] = {0};
    char toDel[1024] = {0};
    divPath(parent, toDel, destPath);
    int ret = findPath(mysql, userid, sockfd, destPath, &destPos);
    if(ret == -1){
        return -1;
    }
    char sql[1024] = {0};
    sprintf(sql, "select id, fileMD5Value, fileType from file_info where parentId = %d and fileName = '%s';", destPos, toDel);
    int qret = mysql_query(mysql, sql);
    MYSQL_RES *rows = mysql_store_result(mysql);
    MYSQL_ROW row = mysql_fetch_row(rows);
    char MD5[1024] = {0};
    char fileType[4] = {0};
    int toDelId = atoi(row[0]);
    strcpy(MD5, row[1]);
    strcpy(fileType, row[2]);
    if(fileType[0] == 'd'){
        bzero(sql, 1024);
        sprintf(sql, "select count(*) from file_info where parentId = %d;", toDelId);
        qret = mysql_query(mysql, sql);
        rows = mysql_store_result(mysql);
        row = mysql_fetch_row(rows);
        int count = atoi(row[0]);
        if(count){
            RETERROR2("Not an empty dir.");
            return -1;
        }
    }
    bzero(sql, 1024);
    sprintf(sql, "delete from file_info where id = %d;", toDelId);
    qret = mysql_query(mysql, sql);
    if(qret == 0){
        RETOK("REMOVE success.");
    }
    return 0;
}

